﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Serialization.Formatters;
using System.Text;
using Common;

namespace ConsoleClient
{
    class Program
    {
        //private const int SERVER_PORT = 8080;

        private static T GetRemotingService<T>(string serverIpAddr, string serviceUri)
        {
            return (T)Activator.GetObject(typeof(T), string.Format("tcp://{0}:8080/{1}", serverIpAddr, serviceUri));
        }

        private static void InitializeChannel()
        {
            BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
            BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
            serverProvider.TypeFilterLevel = TypeFilterLevel.Full;

            IDictionary props = new Hashtable();
            props["port"] = 0;
            TcpChannel channel = new TcpChannel(props, clientProvider, serverProvider);
            ChannelServices.RegisterChannel(channel);
        }

        private static string GetIpAddressText()
        {
            IPHostEntry ipHostEntry = Dns.GetHostEntry(Environment.MachineName);
            IPAddress ipAddress = ipHostEntry.AddressList.FirstOrDefault(o => o.AddressFamily == AddressFamily.InterNetwork);
            return ipAddress != null ? ipAddress.ToString() : string.Empty;
        }

        private static void Run(string serverIpAddr)
        {
            var chatService = GetRemotingService<IChatService>(serverIpAddr, "ChatService");
            string ipAddrText = GetIpAddressText();

//            List<string> messages = new List<string>();
//
//            ChatEventWrapper chatEventWrapper = new ChatEventWrapper();
//
//            chatEventWrapper.Broadcast += m =>
//                {
//                    lock (messages)
//                    {
//                        messages.Add(m);
//                    }
//                };
//
//            chatService.Broadcast += chatEventWrapper.Broadcasting;

            Broadcast broadcast = new Broadcast();

            try
            {
                chatService.SetBroadcast(broadcast);
            }
            catch (Exception)
            {

                throw;
            }

            while (true)
            {
                string cmd = Console.ReadLine();
                if (cmd.Equals("q", StringComparison.OrdinalIgnoreCase))
                {
                    break;
                }

                if (!string.IsNullOrEmpty(cmd))
                {
                    chatService.Talk(ipAddrText, cmd);
                }

//                lock (messages)
//                {
//                    messages.ForEach(Console.WriteLine);
//                    messages.Clear();
//                }
                broadcast.GetResentMessages().ForEach(Console.WriteLine);
            }
        }

        static void Main(string[] args)
        {
            Console.Write("Server Ip:");
            string serverIpAddr = Console.ReadLine();
            if (string.IsNullOrEmpty(serverIpAddr))
            {
                serverIpAddr = "localhost";
            }

            InitializeChannel();

            try
            {
                Run(serverIpAddr);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.ReadKey();
            }
        }
    }
}
